
#include "../../Command.h"

#include "../../User.h"
#include "../../NLogic/Static.h"

namespace ProjectZ { namespace NCommand {

static void SendAckFail(User * pUser, int16_t ack)
{
	::Network::Packet * pAck = ::Network::GETPACKETPOOL()->SEND_NEW();
	if (ack == ACK_OK)
		* pAck << static_cast<int16_t>(ack) << static_cast<uint16_t>(0);
	else
		* pAck << static_cast<int16_t>(ack);

	pAck->MakePacket(CMD_SC_REQ_DUNGEON_PARTY_LIST);
	pUser->Send(pAck);
}

void Command::CS_REQ_DUNGEON_PARTY_LIST(User * pUser, ::Network::Packet *pPacket)
{
	/*\
	 * CS_REQ_DUNGEON_PARTY_LIST               0x1124
	{
			   u16 u16dungeon_tid;
			   u8  u8dugeon_difficulty;
	}
	SC_REQ_DUNGEON_PARTY_LIST               0x1125
	{
			   s16 sAck;                               /// 생성된 파티 없음
			   u16 count                               /// 던젼/난이도가 같은 생성된 파티 갯수만큼
			   {
						 u32 u32room_number;                         /// 방번호 고유값 파티 시퀀스와 같으면 별도로 필요하지 않음
						 u8 u8dugeon_difficulty;
						 u8 u8party_member_num;		/// 모집하는 파티원 수 1 or 2
						 u8 count                     /// 파티원 수만큼
						 {
									u8 u8class_type;
									u16 u16lv;
						 }
			   }
	}
	 *
	 */

	NLogic::Space * pWorld = pUser->GetSpace();
	if (NULL == pWorld)
	{
		DEBUGLOG("CS_REQ_DUNGEON_PARTY_LIST NULL == pWorld");
		SendAckFail(pUser, ACK_NO_SPACE);
		return;
	}

	if (pWorld->GetData()._spaceType != NLogic::Space::SpaceType::WORLD)
	{
		DEBUGLOG("CS_REQ_DUNGEON_PARTY_LIST pWorld->GetData()._spaceType != NLogic::Space::SpaceType::WORLD");
		SendAckFail(pUser, ACK_NO_SPACE);
		return;
	}

	if (pUser->GetEnumState() != User::EnumState::__NONE__)
	{
		DEBUGLOG("CS_REQ_DUNGEON_PARTY_LIST pUser->GetEnumState() != User::EnumState::__NONE__");
		SendAckFail(pUser, ACK_UNKNOWN_ERROR);
		return;
	}

	PREPARE_PACKET;

	uint16_t u16dungeon_tid = 0;
	uint8_t u8difficulty = 0;

	* pPacket >> u16dungeon_tid >> u8difficulty;

	NLogic::Static::PARTYROOMTREE & clsPartyRoomTree = NLogic::Static::Instance().GETPARTYROOMTREE();
	auto itrs = clsPartyRoomTree.find( NLogic::Key(u16dungeon_tid, u8difficulty) );

	if (itrs == clsPartyRoomTree.end())
	{
		SendAckFail(pUser, ACK_OK);
		return;
	}

	NLogic::Static::SPACEVECTOR & spaceVector = itrs->second;

	if (spaceVector.size() <= 0)
	{
		SendAckFail(pUser, ACK_OK);
		return;
	}

	std::vector<NLogic::Space * > clsSpaceVector;
	auto spaceItr = spaceVector.begin();
	for ( ;spaceItr != spaceVector.end(); ++spaceItr)
	{
		NLogic::Space * pSpace = ( * spaceItr );
		NLogic::Indexer * pIndexer = pSpace->GetIndexer();
		if (NULL == pIndexer)
			continue;

		NLogic::Party * pParty = pSpace->GetParty();
		if (NULL == pParty)
			continue;

		if (static_cast<int>(pParty->GetAllUserTree().size()) >= pSpace->GetData()._maxUser + 1)
			continue;

		if (pParty->GetState() != NLogic::Party::State::NEW_PARTY_ROOM_WAIT)
			continue;

		clsSpaceVector.push_back(pSpace);
	}

	::Network::Packet * pAck = ::Network::GETPACKETPOOL()->SEND_NEW();
	* pAck << static_cast<int16_t>(ACK_OK);
	* pAck << static_cast<uint16_t>(clsSpaceVector.size());
	DEBUGLOG("ROOM COUNT : %d", clsSpaceVector.size());

	auto openSpaceItr = clsSpaceVector.begin();
	for ( ;openSpaceItr != clsSpaceVector.end(); ++openSpaceItr)
	{
		NLogic::Space * pOpenSpace = ( * openSpaceItr );
		NLogic::Indexer * pIndexer = pOpenSpace->GetIndexer();
		NLogic::Party * pParty = pOpenSpace->GetParty();

		uint32_t u32room_number = pIndexer->GetIndex();
		uint8_t u8dugeon_difficulty = static_cast<uint8_t>(pOpenSpace->GetData()._difficulty);
		uint8_t u8party_member_num = static_cast<uint8_t>(pOpenSpace->GetData()._maxUser);

		DEBUGLOG("u32room_number : %d, u8dugeon_difficulty : %d , u8party_member_num : %d", u32room_number, u8dugeon_difficulty, u8party_member_num);

		auto partyAllUserTree = pParty->GetAllUserTree();
		uint8_t count = partyAllUserTree.size();

		* pAck << u32room_number << u8dugeon_difficulty << u8party_member_num << count;

		DEBUGLOG("userCount : %d", count);

		std::for_each(partyAllUserTree.begin(), partyAllUserTree.end(), [&](NLogic::Party::USERTREE::value_type & pair) {
			User * pUser = pair.second;

			uint8_t u8class_type = static_cast<uint8_t>(pUser->GetCharacterInfo().classtype);
			uint16_t u16lv = static_cast<uint16_t>(pUser->GetCharacterInfo().level);

			* pAck << u8class_type << u16lv;

			DEBUGLOG("u8class_type : %d, u16lv : %d", u8class_type, u16lv);
		} );
	}

	pAck->MakePacket(CMD_SC_REQ_DUNGEON_PARTY_LIST);
	pUser->Send(pAck);
	clsSpaceVector.clear();

}

} /*NCommand*/ } /*ProjectZ*/
